let appUxFileTemplate = `<script>
/**
 * 应用级别的配置，供所有页面公用
 */

export default {
  onCreate() {}
}
</script>
`

let selfCloseInputTagJsFileTemplate = `/**
 * @file: selfCloseInputTag.js
 * @desc: 遍历指定目录下 .ux 文件，将其中 input 标签由 <input **></input> 转换为 <input ** />
 * @date: 2019-01-23
 */

const fs = require('fs')
const path = require('path')

const quickappCodePath = './src/'

const main = codePath => {
  const traversing = cpath => {
    const files = fs.readdirSync(cpath)
    files.forEach(fileName => {
      const fPath = path.join(cpath, fileName)
      const stats = fs.statSync(fPath)
      stats.isDirectory() && traversing(fPath)
      stats.isFile() && fPath.endsWith('.ux') && matchAndReplace(fPath)
    })
  }
  traversing(codePath)
}

const matchAndReplace = path => {
  const pageContent = fs.readFileSync(path, 'UTF-8')
  const newContent = pageContent.replace(
    /(<)([\\s]*?)(input\\b[^\\/]*?)>[\\s\\S]*?<\\/input>/gm,
    '$1$3 />'
  )
  fs.writeFile(path, newContent, error => {
    if (error) throw \`Something went wrong: \${error}\`
  })
}

main(quickappCodePath)
`

let genIndexJsFileTemplate = `/**
 * @desc: gen script command，make a new page generated by one click.
 * @author: nicejade
 */

const fs = require('fs')
const path = require('path')
const colors = require('colors')

const newFolderName = process.argv[2]

String.prototype.firstUpperCase = function() {
  return this.replace(/\\b(\\w)/g, $1 => {
    return $1.toLowerCase()
  })
}
const resolve = dir => {
  return path.join(__dirname, '../..', dir)
}

const successExecPrint = msg => {
  console.log(
    colors.green(\`✓ \`) +
      colors.cyan(\`\${msg} \`) +
      colors.green('task has been successfully executed.')
  )
}

function createNewPage(newFolderPath) {
  const mReg = new RegExp('@PAGE_CLASS_NAME', 'g')
  const pageContent = fs.readFileSync(\`\${__dirname}/template.ux\`, 'UTF-8')
  const rootClassName = newFolderName
    .firstUpperCase()
    .replace(/([A-Z])/g, '-$1')
    .toLowerCase()
  const newContent = pageContent.replace(mReg, rootClassName)

  fs.mkdirSync(newFolderPath, 0777)
  fs.writeFile(\`\${newFolderPath}/index.ux\`, newContent, error => {
    if (error) throw \`Something went wrong: \${error}\`
  })
  successExecPrint('Create New Page')
}

function saveRouter2Manifest() {
  const manifestPath = resolve('/src/manifest.json')
  let manifestConf = fs.readFileSync(manifestPath, 'UTF-8')
  manifestConf = JSON.parse(manifestConf)
  const routerPages = manifestConf.router.pages
  routerPages[\`pages/\${newFolderName}\`] = {
    component: 'index'
  }
  manifestConf = JSON.stringify(manifestConf, null, 2)
  fs.writeFile(manifestPath, manifestConf, error => {
    if (error) throw \`Something went wrong[@saveRouter2Manifest]: \${error}\`
  })
  successExecPrint('Save Router Into Manifest')
}

function main() {
  if (!newFolderName) {
    return console.warn(
      \`⚠️  Please enter the name of the page you want to create.\`.underline.red
    )
  }

  const folderNameReg = /^[A-Z][[A-Za-z0-9]+$/
  if (!folderNameReg.test(newFolderName)) {
    return console.warn(
      \`⚠️  Please enter the standard Folder name. Eg: XyzAbcde.\`.underline.red
    )
  }

  const newFolderPath = path.join(__dirname, \`../../src/pages/\${newFolderName}\`)
  const isExist = fs.existsSync(newFolderPath)

  if (isExist) {
    return console.warn(
      \`⚠️  \${newFolderName} already exists in the /src/pages/ directory.\`
        .underline.red
    )
  }
  createNewPage(newFolderPath)
  saveRouter2Manifest()
}

main()
`

let genTemplateUxFileTemplate = `
<template>
  <div class="wrapper">
    <text class="title">{{ title }}</text>
  </div>
</template>

<script>
export default {
  private: {
    title: '欢迎体验快应用开发'
  },

  onInit() {}
}
</script>

<style lang="less">
@import './../../assets/styles/style.less';

.wrapper {
  .flex-box-mixins(column, center, center);
  .title {
    font-size: 8 * @size-factor;
    text-align: center;
    color: @black;
  }
}
</style>
`

let previewJsonFileTemplate = `{
    "modeOptions": {
      "current": -1,
      "list": []
    }
}
`

let packageJsonFileJinjaTemplate = `{
  "name": {{ appName }},
  "version": "1.0.0",
  "description": {{ appDescription }},
  "packageManager": "pnpm@7.1.0",
  "scripts": {
    "gen": "node ./scripts/gen/index.js",
    "precommit-msg": "echo '🚧 start pre-commit checks ...' && exit 0",
    "prettier": "node ./scripts/selfCloseInputTag.js && prettier --write \\"src/**/*.{ux,js,json,less,scss,css,pcss,md,vue}\\""
  },
  "devDependencies": {
    "@babel/runtime": "^7.12.5",
    "@types/quickapp": "npm:quickapp-interface@^1.0.0",
    "colors": "^1.4.0",
    "husky": "^7.0.1",
    "lint-staged": "^11.0.1",
    "prettier": "^2.3.2",
    "prettier-plugin-ux": "^0.3.0"
  },
  "prettier": {
    "singleQuote": true,
    "semi": false,
    "printWidth": 80,
    "proseWrap": "never",
    "tabWidth": 2
  },
  "husky": {
    "hooks": {
      "pre-commit": "yarn run precommit-msg && lint-staged"
    }
  },
  "lint-staged": {
    "**/**.{ux,js,json,less,scss,css,pcss,md,vue}": [
      "prettier --write",
      "git add"
    ]
  }
}
`

let jsconfigJsonFileTemplate = `{
  "compilerOptions": {
    "noImplicitAny": false,
    "strict": true,
    "noUnusedLocals": true,
    "noImplicitThis": true,
    "noUnusedParameters": true,
    "allowSyntheticDefaultImports": true,
    "forceConsistentCasingInFileNames": true,
    "esModuleInterop": true,
    "resolveJsonModule": true,
    "skipLibCheck": true,
    "checkJs": true
  },
  "include": [
    "src/**/*"
  ],
  "exclude": [
    "node_modules"
  ]
}
`

let prettierignoreFileTemplate = `package.json
manifest.json
README.md

# assets/js
src/assets/js/*.js
`

let gitignoreFileTemplate = `.DS_Store
node_modules
/dist
/build

# sign

# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*
.ide
.quickapp.preview.json
`

let manifestJsonFileJinjaTemplate = `{
  "package": "com.example.demo",
  "name": {{ appName }},
  "versionName": "1.0.0",
  "versionCode": 1,
  "icon": "/assets/images/logo.png",
  "features": [
    {
      "name": "system.prompt"
    },
    {
      "name": "system.router"
    },
    {
      "name": "system.shortcut"
    },
    {
      "name": "system.fetch"
    }
  ],
  "permissions": [
    {
      "origin": "*"
    }
  ],
  "appType": "quickapp",
  "template/official": "demo-template",
  "config": {
    "logLevel": "debug"
  },
  "router": {
    "entry": {{ entryPage }},
    "pages": {{ routerPages }}
  },
  "display": {
    "titleBarBackgroundColor": "#f2f2f2",
    "titleBarTextColor": "#414141",
    "pages": {{ displayPages }}
  }
}
`

let assetsStylesMixinsLessFileTemplate = `.flex-box-mixins (@column, @justify, @align) {
  flex-direction: @column;
  justify-content: @justify;
  align-items: @align;
}
`

let assetsStylesStyleLessFileTemplate = `@import './variables.less';
@import './mixins.less';
`

let assetsStylesVariablesLessFileTemplate = `@brand: #09ba07;

@white: #ffffff;
@black: #000000;
@grey: #9393aa;
@red: #fa0101;
@green: #ffff00;

@size-factor: 5px;
`

let helperAjaxJsFileTemplate = `/**
 * 封装了一些网络请求方法，方便通过 Promise 的形式请求接口
 */
import $fetch from '@system.fetch'
import { queryString } from './utils'
const TIMEOUT = 20000

Promise.prototype.finally = function(callback) {
  const P = this.constructor
  return this.then(
    value => P.resolve(callback()).then(() => value),
    reason =>
      P.resolve(callback()).then(() => {
        throw reason
      })
  )
}

/**
 * 调用快应用 fetch 接口做网络请求
 * @param params
 */
function fetchPromise(params) {
  return new Promise((resolve, reject) => {
    $fetch
      .fetch({
        url: params.url,
        method: params.method,
        data: params.data
      })
      .then(response => {
        const result = response.data
        const content = JSON.parse(result.data)
        /* @desc: 可跟具体不同业务接口数据，返回你所需要的部分，使得使用尽可能便捷 */
        content.success ? resolve(content.value) : resolve(content.message)
      })
      .catch((error, code) => {
        console.log(\`🐛 request fail, code = \${code}\`)
        reject(error)
      })
      .finally(() => {
        console.log(\`✔️ request @\${params.url} has been completed.\`)
        resolve()
      })
  })
}

/**
 * 处理网络请求，timeout 是网络请求超时之后返回，默认 20s 可自行修改
 * @param params
 */
function requestHandle(params, timeout = TIMEOUT) {
  try {
    return Promise.race([
      fetchPromise(params),
      new Promise((resolve, reject) => {
        setTimeout(() => {
          reject(new Error('网络状况不太好，再刷新一次？'))
        }, timeout)
      })
    ])
  } catch (error) {
    console.log(error)
  }
}

export default {
  post: function(url, params) {
    return requestHandle({
      method: 'post',
      url: url,
      data: params
    })
  },
  get: function(url, params) {
    return requestHandle({
      method: 'get',
      url: queryString(url, params)
    })
  },
  put: function(url, params) {
    return requestHandle({
      method: 'put',
      url: url,
      data: params
    })
  }
  // 如果，method 您需要更多类型，可自行添加更多方法；
}
`

let helperUtilsJsFileTemplate = `/**
 * 您可以将常用的方法、或系统 API，统一封装，暴露全局，以便各页面、组件调用，而无需 require / import.
 */
 import prompt from '@system.prompt';
  /**
  * 拼接 url 和参数
  */
 export function queryString(url, query) {
   let str = [];
   for (let key in query) {
     str.push(key + '=' + query[key]);
   }
   let paramStr = str.join('&');
   return paramStr ? \`\${url}?\${paramStr}\` : url;
 }
 
 export function showToast(message = '', duration = 0) {
   if (!message) return;
   prompt.showToast({
     message: message,
     duration
   });
 }
`

let helperApisExampleJSFileTemplate = `
import $ajax from '../ajax'

/**
 * @desc 在实际开发中，您可以将 baseUrl 替换为您的请求地址前缀；
 * 备注：如果您不需要发起请求，删除 apis 目录，以及 app.ux 中引用即可；
 */
const baseUrl = 'https://api.exampel.com/'

export function getApi(data) {
  return $ajax.get(\`\${baseUrl}your-project-api\`, data)
} 

export function postOtherApi(data) {
  return $ajax.post(\`\${baseUrl}your-project-api\`, data)
}
`

module.exports = {
    appUxFileTemplate,
    selfCloseInputTagJsFileTemplate,
    genIndexJsFileTemplate,
    genTemplateUxFileTemplate,
    previewJsonFileTemplate,
    jsconfigJsonFileTemplate,
    packageJsonFileJinjaTemplate,
    prettierignoreFileTemplate,
    gitignoreFileTemplate,
    manifestJsonFileJinjaTemplate,
    assetsStylesMixinsLessFileTemplate,
    assetsStylesStyleLessFileTemplate,
    assetsStylesVariablesLessFileTemplate,
    helperAjaxJsFileTemplate,
    helperUtilsJsFileTemplate,
    helperApisExampleJSFileTemplate
}